using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Logic.Sequential;
using System.Collections;
using Data.DataTranslator;
using System.IO;
using System.Drawing.Imaging;

namespace Gui
{
    public partial class SequentialResults : UserControl
    {
        private static int RawColor=0;
        private int numberOfClusters;
        private ArrayList[] clusters;
        private ArrayList saveData;
        private Cell[] results;
        private int[] widthOfCols;

        #region private class for sorting
        class ListViewItemComparer : IComparer
        {
            private int col;
            public ListViewItemComparer()
            {
                col = 0;
            }
            public ListViewItemComparer(int column)
            {
                col = column;
            }
            public int Compare(object x, object y)
            {
                int returnVal = -1;
                returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
                ((ListViewItem)y).SubItems[col].Text);
                if (RawColor == 0)
                {
                    RawColor = 1;
                    ((ListViewItem)x).BackColor = Color.Cyan;
                    ((ListViewItem)y).BackColor = Color.Honeydew;
                }
                else
                {
                    RawColor = 0;
                    ((ListViewItem)x).BackColor = Color.Cyan;
                    ((ListViewItem)x).BackColor = Color.Honeydew;
                }
                return returnVal;
            }
        }
        #endregion

        private class saveCell
        {
            private string nameOfGenome;
            private int clusterNumber;
            private int genomeCode;
            public saveCell(string nameOfGenome, int clusterNumber, int genomeCode)
            {
                this.nameOfGenome = nameOfGenome;
                this.clusterNumber = clusterNumber;
                this.genomeCode = genomeCode;
            }

            public override string ToString()
            {
                return  this.genomeCode.ToString() + "\t" + this.clusterNumber.ToString() + "\t"+ this.nameOfGenome;
            }
        }
        #region constructors
        public SequentialResults()
        {
            InitializeComponent();
        }
        #endregion

        #region getters and seters
        public string numberOfIterations
        {
            set
            {
                this.numberOfIterationsLabel.Text = value;
            }
        }
        public string numOfClusters
        {
            set
            {
                this.numberOfClustersLabel.Text = value;
            }
        }
        public string maxL
        {
            set
            {
                this.maxLLabel.Text = value;
            }
        }
        public string epsilon
        {
            set
            {
                this.epsilonLabel.Text = value;
            }
        }
        #endregion

        #region methods
        public int NumberOfClusters
        {
            set
            {
                this.numberOfClusters = value;
            }
        }

        public void InitializeDataToShow(Cell[] results, int numberOfClusters)
        {
            //initialize the number of arraylists
            this.numberOfClusters = numberOfClusters;
            this.clusters = new ArrayList[this.numberOfClusters];
            this.results = results;
            for (int i = 0; i < this.numberOfClusters; i++)
                this.clusters[i] = new ArrayList();

            //Gets the partition of the genomes
            foreach (Cell c in results)
                this.clusters[c.GroupNumber - 1].Add(c.GenomeNumber);
            //Only a way of knowing the number of properties
            string[] properties = kDimMap.getPropertiesOfGenome((int)this.clusters[0][0]);
            this.widthOfCols = new int[properties.Length+1];
            properties = null;
            ImageList imageListSmall = new ImageList();
            for (int i = 0; i < this.numberOfClusters; i++)
            {
                Bitmap bm = new Bitmap(16,16);
                for (int loop1 = 15; loop1 >= 0; loop1--)
                    for (int loop2 = 15; loop2 >= 0; loop2--)
                        bm.SetPixel(loop1, loop2, kDimMap.HLStoRGB((int)((i / (double)this.numberOfClusters)*240), 120, 240));
                imageListSmall.Images.Add(bm);
            }
            this.genomeListView.SmallImageList = imageListSmall;
 
            ShowClusterNames();
            setColsWidth();
        }

        private void setColsWidth()
        {
            int allColsWidth = this.genomeListView.Width-20;
            int allMaximalLengths = 0;
            for (int i = 0; i < this.widthOfCols.Length; i++)
                allMaximalLengths = allMaximalLengths + this.widthOfCols[i];
            for (int i = 0; i < this.widthOfCols.Length; i++)
                this.genomeListView.Columns[i].Width = (int)((this.widthOfCols[i] / (double)allMaximalLengths) *allColsWidth);
        }

        private void buildSaveDataArray()
        {
            saveData = new ArrayList();
            for (int i = 0; i < this.clusters.Length; i++)
                AddItemsAtCluster(i);
        }

        private void AddItemsAtCluster(int clusterId)
        {
            for (int i=0; i < this.clusters[clusterId].Count; i++)
                saveData.Add(new saveCell(kDimMap.getGenomeName((int)(this.clusters[clusterId][i])), clusterId + 1, (int)(this.clusters[clusterId][i])));
        }

        private void ShowAllGenomeDetails()
        {
            for (int i = 0; i < this.numberOfClusters; i++)
                this.ShowGenomeDetailsOfCluster(i);
            
        }

        private void ShowClusterNames()
        {
            this.clusterNamesListBox.Items.Clear();
            this.clusterNamesListBox.Items.Add("All genomes");
            for (int i = 1; i <= this.numberOfClusters; i++)
                this.clusterNamesListBox.Items.Add("Cluster No." + i.ToString());
            this.clusterNamesListBox.SelectedIndex = 0;
        }

        private void ShowGenomeDetailsOfCluster(int clusterId)
        {
            ListViewItem lvi;

            for (int i = 0; i < this.clusters[clusterId].Count; i++)
            {
                string genomeName = kDimMap.getGenomeName((int)this.clusters[clusterId][i]);
                if (this.widthOfCols[0] < genomeName.Length)
                    this.widthOfCols[0] = genomeName.Length;
                string[] properties = kDimMap.getPropertiesOfGenome((int)this.clusters[clusterId][i]);
                string[] oneRaw = new string[properties.Length+1];
                oneRaw[0] = genomeName;
                for (int j = 1; j < oneRaw.Length; j++)
                {
                    oneRaw[j] = properties[j - 1];
                    if (this.widthOfCols[j] < properties[j - 1].Length)
                        this.widthOfCols[j] = properties[j - 1].Length;
                }
                if (RawColor == 0)
                {
                    RawColor = 1;
                    lvi = new ListViewItem(oneRaw, clusterId, SystemColors.ControlText, Color.Cyan, null);
                }
                else
                {
                    RawColor = 0;
                    lvi = new ListViewItem(oneRaw, clusterId, SystemColors.ControlText, Color.Honeydew, null);
                }
                this.genomeListView.Items.Add(lvi);
            }
        }


        #endregion

        #region events
        private void clusterNamesListBox_SelectedIndexChanged(object sender, EventArgs e)
        {            
            int selectedIndex = this.clusterNamesListBox.SelectedIndex;
            this.genomeListView.Items.Clear();
            if (selectedIndex == 0)
            {
                this.genomeListView.ListViewItemSorter = null;
                ShowAllGenomeDetails();
            }
            else
                ShowGenomeDetailsOfCluster(this.clusterNamesListBox.SelectedIndex - 1);
        }

        private void genomeListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            //Create a new object of the private calss that implements IComparer
            this.genomeListView.ListViewItemSorter = new ListViewItemComparer(e.Column);
            //Calling the sort method
            this.genomeListView.Sort();
        }
        #endregion

        private void chart1_Click(object sender, EventArgs e)
        {

        }

        private void SaveSequentialResultsButton_Click(object sender, EventArgs e)
        {
            buildSaveDataArray();
            this.saveFile1.InitilizeData(this.saveData, "<Sequential Results>");
            this.saveFile1.Visible = true;
        }
    }
}
